package menu

import (
	"fmt"

	"github.com/Masterminds/squirrel"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/copier"
	"go-api-template/api/http"
	"go-api-template/api/models/system"
	e2 "go-api-template/internal/e"
	"go-api-template/service"
)

type SaveReq struct {
	ID       string `json:"id"`
	Path     string `json:"path" binding:"required"` // MenuKey(Url)
	Name     string `json:"name" binding:"required"` // 名称
	EnName   string `json:"en_name"`                 // 英文名
	CnName   string `json:"cn_name"`                 // 中文名
	IconType string `json:"icon_type"`               // IconFont Type
	Sort     int    `json:"sort"`                    // 排序
}
type SaveResp struct {
	ID string `json:"id"`
}

func (req *SaveReq) Request(ctx *gin.Context, s *service.Service) (http.Resp, error) {
	return req.Do(ctx, s)
}
func (req *SaveReq) Do(ctx *gin.Context, s *service.Service) (resp http.Resp, err error) {
	var data SaveResp
	var menu system.Menu

	_ = copier.Copy(&menu, &req)

	if req.ID != "" {
		s.Db.Updates(&menu)
	} else {
		s.Db.Where("name = ?", req.Name).Or("path = ?", req.Path).First(&menu)
		if menu.ID != "" {
			resp.SetCode(e2.RoleNameRepeat)
			return
		}
		s.Db.Create(&menu)
	}

	data.ID = menu.ID

	resp.SetData(data)
	return
}

type ListReq struct {
	Name string `form:"name"`
	Path string `form:"path"`
	http.PaginationReq
}
type ListResp struct {
	http.RespList[system.Menu]
}

func (req *ListReq) Request(ctx *gin.Context, s *service.Service) (http.Resp, error) {
	return req.Do(ctx, s)
}
func (req *ListReq) Do(_ *gin.Context, s *service.Service) (resp http.Resp, err error) {
	var data ListResp
	var menus []system.Menu
	req.query(s, &menus)

	data.Total = req.query(s, nil)
	for _, menu := range menus {
		var item system.Menu
		_ = copier.Copy(&item, &menu)
		data.Items = append(data.Items, item)
	}

	resp.SetData(data)
	return
}
func (req *ListReq) query(s *service.Service, items *[]system.Menu) (count int) {
	itemsSq := squirrel.Select([]string{
		"*",
	}...).
		From("system_menu")

	if req.Name != "" {
		itemsSq = itemsSq.Where("name like ?", fmt.Sprint("%", req.Name, "%"))
	}

	if items == nil {
		sql, value, _ := itemsSq.ToSql()
		s.Db.Raw(sql, value...).Scan(&count)
	} else {
		sql, value, _ := itemsSq.ToSql()
		s.Db.Raw(sql, value...).Debug().Scan(items)
	}
	return
}
